package com.kira.scaffoldmvc.ShutDownHook;

import com.kira.scaffoldmvc.Strategy.IBeanType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class ThreadPoolCloseStrategy implements CloseStrategy {


    @Autowired(required = false)
    private Map<String, ThreadPoolExecutor> threadPoolExecutorMap;

    @Override
    public void close() {
        log.info("Spring容器销毁，开始关闭线程池...");
        shutdownAllExecutorServices();
    }

    //在 MultipleBeanContainer 和 DefaultBeanContainer 中，该方法的返回值会被用作存储策略 Bean 的 Map 集合的键（Key）
    @Override
    public String beanType() {
        //close作为Key,存储所有的关闭策略
        return "close";
    }


    /**
     * 优雅关闭所有线程池，确保所有任务执行完成
     */
    public void shutdownAllExecutorServices() {
        if (threadPoolExecutorMap != null && !threadPoolExecutorMap.isEmpty()) {
            threadPoolExecutorMap.forEach((name, executor) -> {
                log.info("正在关闭线程池: " + name);
                shutdownExecutorServiceCompletely(name, executor);
            });
        }
    }

    /**
     * 优雅关闭线程池，确保所有任务执行完成
     *
     * @param poolName 线程池名称
     * @param executor 线程池实例
     */
    private void shutdownExecutorServiceCompletely(String poolName, ExecutorService executor) {
        // 停止接收新任务
        executor.shutdown();
        // 等待所有任务执行完成，不设置超时
        try {
            // 定期检查线程池状态
            while (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                // 输出剩余任务信息，方便监控
                if (executor instanceof ThreadPoolExecutor) {
                    ThreadPoolExecutor threadPool = (ThreadPoolExecutor) executor;
                    log.info(
                            "线程池[{}]关闭中: 活跃线程数={}, 队列任务数={}, 已完成任务数={}, 总任务数={}",
                            poolName,
                            threadPool.getActiveCount(),
                            threadPool.getQueue().size(),
                            threadPool.getCompletedTaskCount(),
                            threadPool.getTaskCount()
                    );
                }
            }
            log.info("线程池[{}]已完全关闭，所有任务执行完成", poolName);
        } catch (InterruptedException ie) {
            // 被中断时，继续尝试关闭
            log.info("线程池[{}]关闭过程被中断，继续尝试关闭...", poolName);
            Thread.currentThread().interrupt();//将中断标志为设为true,方面后面逻辑拓展
            //当我们抛出错误后,为了保证这个线程池的任务执行完我们选择继续等待,而不是shutdownNow()
            // 注意：这里不调用shutdownNow()，确保任务完成
        }
    }


}
